package com.sunchen.asc.service.user.server;


import com.alibaba.fastjson.JSONObject;
import com.sunchen.asc.service.common.ResultResponse;
import com.sunchen.asc.service.common.ResultUtil;
import com.sunchen.asc.service.user.api.UserService;
import com.sunchen.asc.service.user.domain.Authentication;
import com.sunchen.asc.service.user.domain.Role;
import com.sunchen.asc.service.user.domain.User;
import com.sunchen.asc.service.user.dto.UserDto;
import com.sunchen.asc.service.user.repository.UserRepository;
import com.sunchen.asc.service.user.vo.CurrentUser;
import com.sunchen.asc.service.user.vo.RoleVo;
import com.sunchen.asc.service.user.vo.UserVo;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@DubboService(retries = 0)
public class UserServiceImpl implements UserService {

    @Autowired
    UserRepository userRepository;

    public ResultResponse creatUser(UserDto userDto){
        User user = new User(userDto);
        user.setDeleteFlag(0);
        //user.setCreateUser();
        userRepository.save(user);
        return ResultUtil.success("创建成功");
    }

    public ResultResponse editUser(UserDto userDto){
        User user = userRepository.getOne(userDto.getId());
        user.setName(userDto.getName());
        user.setSex(userDto.getSex());
        user.setUserName(userDto.getUserName());
        user.setTel(userDto.getTel());
        user.setEmail(userDto.getEmail());
        user.setDescription(userDto.getDescription());
        user.setStatus(userDto.getStatus());
        userRepository.save(user);
        return ResultUtil.success("修改成功");
    }

    public ResultResponse deleteUser(Long id){

        User user = userRepository.getOne(id);
        user.setDeleteFlag(1);
        user.setDeleteTime(new Timestamp(System.currentTimeMillis()));
        //user.setDeleteUser();
        List<Role> roles = new ArrayList<>();
        user.setRoles(roles);

        userRepository.save(user);
        return ResultUtil.success("删除成功");
    }

    public ResultResponse setStatus(Long id, int status){

        User user = userRepository.getOne(id);
        user.setStatus(status);

        userRepository.save(user);
        return ResultUtil.success("修改成功");
    }

    public Page<UserVo> getUserList(Pageable pageable, String name, String userName) {

        Page<User> resultPage = null;
        Specification specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                List<Predicate> predicates = new ArrayList<>();
                Predicate delete = criteriaBuilder.equal(root.get("deleteFlag") , 0);
                predicates.add(delete);

                if (name != null && name.length() > 0){
                    Predicate p = criteriaBuilder.like(root.get("name") , "%"+name+"%");
                    predicates.add(p);
                }
                if (userName != null && userName.length() > 0){
                    Predicate p = criteriaBuilder.like(root.get("userName") , "%"+userName+"%");
                    predicates.add(p);
                }
                Predicate[] pre = new Predicate[predicates.size()];
                return criteriaBuilder.and(predicates.toArray(pre));
            }
        };
        resultPage =userRepository.findAll(specification,pageable);

        List<UserVo> dtoList = resultPage.getContent().stream().map(user ->{
            UserVo vo = new UserVo();
            vo.setId(user.getId().toString());
            vo.setName(user.getName());
            vo.setUserName(user.getUserName());
            vo.setTel(user.getTel());
            vo.setSex(user.getSex());
            vo.setEmail(user.getEmail());
            vo.setStatus(user.getStatus());
            vo.setDescription(user.getDescription());
            vo.setRoleStr(user.getRoles().parallelStream().map(Role::getTitle).collect(Collectors.joining(",")));
            return vo;
        }).collect(Collectors.toList());
        Page<UserVo> dtoPage = new PageImpl<>(dtoList, resultPage.getPageable(), resultPage.getTotalElements());
        return dtoPage;
    }

    public JSONObject findTheOnlyUserNameCreat(String userName) {

        JSONObject res = new JSONObject();
        User byName = userRepository.findFirstByUserNameAndDeleteFlag(userName,0);
        if(null != byName){
            res.put("valid",false);
            res.put("message","已存在");
        }else{
            res.put("valid",true);
            res.put("message","可用");
        }
        return res;
    }

    public JSONObject findTheOnlyUserNameModify(String userName, Long id) {

        JSONObject res = new JSONObject();
        String oldName = userRepository.findUserNameById(id);
        if (oldName.equals(userName)){
            res.put("valid",true);
            res.put("message","可用");
            return res;
        }
        User byName = userRepository.findFirstByUserNameAndDeleteFlag(userName,0);
        if(null != byName){
            res.put("valid",false);
            res.put("message","已存在");
        }else{
            res.put("valid",true);
            res.put("message","可用");
        }
        return res;
    }

    public ResultResponse setUserRole(Long id, List<Long> roleIds) {

        User user = userRepository.getOne(id);
        List<Role> roles = new ArrayList<>();
        for (Long roleId:roleIds){
            Role role = new Role();
            role.setId(roleId);
            roles.add(role);
        }
        user.setRoles(roles);
        //user.setUserName();
        userRepository.save(user);
        return ResultUtil.success("修改成功");
    }

    public ResultResponse getUser(String userName) {

        User user = userRepository.findFirstByUserNameAndDeleteFlag(userName,0);
        if (user == null){
            return ResultUtil.failed("未找到此用户");
        }
        UserDto userDto = new UserDto();
        userDto.setUserName(user.getUserName());
        userDto.setId(user.getId());
        userDto.setName(user.getName());
        userDto.setTel(user.getTel());
        userDto.setEmail(user.getEmail());
        userDto.setSex(user.getSex());
        userDto.setCreateTime(user.getCreateTime());
        userDto.setCreateUser(user.getCreateUser());
        userDto.setUpdateTime(user.getUpdateTime());
        userDto.setUpdateUser(user.getUpdateUser());
        userDto.setPassword(user.getPassword());
        userDto.setStatus(user.getStatus());
        userDto.setDescription(user.getDescription());
        List<String> roles = new ArrayList<>();
        user.getRoles().forEach(item->roles.add(item.getName()));
        userDto.setRoles(roles);
//        BeanUtils.copyProperties(user , dto);
        return ResultUtil.success(userDto);
    }

    public ResultResponse resetPassword(Long id) {

        User user = userRepository.getOne(id);
        user.setPassword("123456");
        //user.setUpdateUser();
        userRepository.save(user);
        return ResultUtil.success("修改成功");
    }

    public ResultResponse userDetail(Long id) {

        User user = userRepository.getOne(id);
        UserVo userVo = new UserVo();
        userVo.setId(user.getId().toString());
        userVo.setName(user.getName());
        userVo.setUserName(user.getUserName());
        userVo.setTel(user.getTel());
        userVo.setSex(user.getSex());
        userVo.setEmail(user.getEmail());
        userVo.setStatus(user.getStatus());
        userVo.setDescription(user.getDescription());
        userVo.setRoleVos(user.getRoles().stream().map(role ->{
            RoleVo roleVo = new RoleVo();
            roleVo.setId(role.getId().toString());
            roleVo.setName(role.getName());
            roleVo.setStatus(role.getStatus());
            roleVo.setTitle(role.getTitle());
            roleVo.setDescription(role.getDescription());
            return roleVo;
        }).collect(Collectors.toList()));

        return ResultUtil.success(userVo);
    }

    public ResultResponse current(Long id) {

        User user = userRepository.getOne(id);
        CurrentUser currentUser = new CurrentUser();
        currentUser.setId(user.getId().toString());
        currentUser.setName(user.getName());
        currentUser.setUserName(user.getUserName());
        currentUser.setTel(user.getTel());
        currentUser.setSex(user.getSex());
        currentUser.setEmail(user.getEmail());
        currentUser.setStatus(user.getStatus());
        currentUser.setDescription(user.getDescription());
        currentUser.setRoles(user.getRoles().stream().map(role -> {
            RoleVo vo = new RoleVo(role.getId(),role.getName(),role.getStatus(),role.getTitle(),role.getDescription());
            return vo;
        }).collect(Collectors.toList()));
        List<String> authStr = userRepository.findAuthByRoleIds(user.getRoles().stream().map(Role::getId).collect(Collectors.toList()));
        currentUser.setAuth(authStr);

        return ResultUtil.success(currentUser);
    }

}